sizegroup: Construct the set of sizegroup peers as a hash table
authorBenjamin Otte <otte@redhat.com>
Sun, 4 Nov 2012 14:47:03 +0000 (15:47 +0100)
committerBenjamin Otte <otte@redhat.com>
Sun, 4 Nov 2012 14:47:03 +0000 (15:47 +0100)
This way we don't need a marker on GtkWidgetParivate that needs to be
unset later, so we have all our data in the same place and can avoid
problems with reentrancy and shenanigans like that.

But the main reason I wrote that is cleaner code.

gtk/gtksizegroup.c
gtk/gtkwidget.c
gtk/gtkwidgetprivate.h

index d1295d0727b2d58f0437663b2124c6f69bb5c344..480806f89a7cbaa89eb2c55a086d03dd9479c6a2 100644 (file)
@@ -147,24 +147,17 @@ static void gtk_size_group_buildable_custom_finished (GtkBuildable  *buildable,
                                                      gpointer       user_data);
 
 static void
-mark_widget_unvisited (GtkWidget *widget)
-{
-  _gtk_widget_set_sizegroup_visited (widget, FALSE);
-}
-
-static void
-add_widget_to_closure (GtkWidget       *widget,
-                      GtkSizeGroupMode mode,
-                      GSList         **widgets)
+add_widget_to_closure (GHashTable       *set,
+                       GtkWidget        *widget,
+                      GtkSizeGroupMode  mode)
 {
   GSList *tmp_groups, *tmp_widgets;
   gboolean hidden;
 
-  if (_gtk_widget_get_sizegroup_visited (widget))
+  if (g_hash_table_lookup (set, widget))
     return;
 
-  *widgets = g_slist_prepend (*widgets, widget);
-  _gtk_widget_set_sizegroup_visited (widget, TRUE);
+  g_hash_table_insert (set, widget, widget);
   hidden = !gtk_widget_is_visible (widget);
 
   for (tmp_groups = _gtk_widget_get_sizegroups (widget); tmp_groups; tmp_groups = tmp_groups->next)
@@ -179,18 +172,19 @@ add_widget_to_closure (GtkWidget       *widget,
         continue;
 
       for (tmp_widgets = tmp_priv->widgets; tmp_widgets; tmp_widgets = tmp_widgets->next)
-        add_widget_to_closure (tmp_widgets->data, mode, widgets);
+        add_widget_to_closure (set, tmp_widgets->data, mode);
     }
 }
 
-static GSList *
+static GHashTable *
 widget_get_size_group_peers (GtkWidget        *widget,
                              GtkSizeGroupMode  mode)
 {
-  GSList *result = NULL;
+  GHashTable *result;
+
+  result = g_hash_table_new (g_direct_hash, g_direct_equal);
 
-  add_widget_to_closure (widget, mode, &result);
-  g_slist_foreach (result, (GFunc) mark_widget_unvisited, NULL);
+  add_widget_to_closure (result, widget, mode);
 
   return result;
 }
@@ -225,12 +219,13 @@ queue_resize_on_widget (GtkWidget          *widget,
                        GtkQueueResizeFlags flags)
 {
   GtkWidget *parent = widget;
-  GSList *tmp_list;
 
   while (parent)
     {
       GSList *widget_groups;
-      GSList *widgets;
+      GHashTable *widgets;
+      GHashTableIter iter;
+      gpointer current;
       
       if (widget == parent && !check_siblings)
        {
@@ -251,41 +246,43 @@ queue_resize_on_widget (GtkWidget          *widget,
 
       widgets = widget_get_size_group_peers (parent, GTK_SIZE_GROUP_HORIZONTAL);
 
-      for (tmp_list = widgets; tmp_list; tmp_list = tmp_list->next)
+      g_hash_table_iter_init (&iter, widgets);
+      while (g_hash_table_iter_next (&iter, &current, NULL))
        {
-         if (tmp_list->data == parent)
+         if (current == parent)
            {
              if (widget == parent)
                real_queue_resize (parent, flags);
            }
-         else if (tmp_list->data == widget)
+         else if (current == widget)
             {
               g_warning ("A container and its child are part of this SizeGroup");
             }
          else
-           queue_resize_on_widget (tmp_list->data, FALSE, flags);
+           queue_resize_on_widget (current, FALSE, flags);
        }
       
-      g_slist_free (widgets);
-             
+      g_hash_table_destroy (widgets);
+      
       widgets = widget_get_size_group_peers (parent, GTK_SIZE_GROUP_VERTICAL);
 
-      for (tmp_list = widgets; tmp_list; tmp_list = tmp_list->next)
+      g_hash_table_iter_init (&iter, widgets);
+      while (g_hash_table_iter_next (&iter, &current, NULL))
        {
-         if (tmp_list->data == parent)
+         if (current == parent)
            {
              if (widget == parent)
                real_queue_resize (parent, flags);
            }
-         else if (tmp_list->data == widget)
+         else if (current == widget)
             {
               g_warning ("A container and its child are part of this SizeGroup");
             }
          else
-           queue_resize_on_widget (tmp_list->data, FALSE, flags);
+           queue_resize_on_widget (current, FALSE, flags);
        }
       
-      g_slist_free (widgets);
+      g_hash_table_destroy (widgets);
 
       parent = gtk_widget_get_parent (parent);
     }
@@ -650,8 +647,9 @@ _gtk_size_group_bump_requisition (GtkWidget        *widget,
                                  gint             *minimum,
                                  gint             *natural)
 {
-  GSList *widgets;
-  GSList *tmp_list;
+  GHashTable *widgets;
+  GHashTableIter iter;
+  gpointer key;
   gint    min_result = 0, nat_result = 0;
 
   if (!_gtk_widget_get_sizegroups (widget))
@@ -659,11 +657,12 @@ _gtk_size_group_bump_requisition (GtkWidget        *widget,
 
   widgets = widget_get_size_group_peers (widget, mode);
 
-  g_slist_foreach (widgets, (GFunc)g_object_ref, NULL);
+  g_hash_table_foreach (widgets, (GHFunc) g_object_ref, NULL);
   
-  for (tmp_list = widgets; tmp_list; tmp_list = tmp_list->next)
+  g_hash_table_iter_init (&iter, widgets);
+  while (g_hash_table_iter_next (&iter, &key, NULL))
     {
-      GtkWidget *tmp_widget = tmp_list->data;
+      GtkWidget *tmp_widget = key;
       gint min_dimension, nat_dimension;
 
       if (tmp_widget == widget)
@@ -680,9 +679,9 @@ _gtk_size_group_bump_requisition (GtkWidget        *widget,
       nat_result = MAX (nat_result, nat_dimension);
     }
 
-  g_slist_foreach (widgets, (GFunc)g_object_unref, NULL);
+  g_hash_table_foreach (widgets, (GHFunc) g_object_unref, NULL);
 
-  g_slist_free (widgets);
+  g_hash_table_destroy (widgets);
 
   *minimum = min_result;
   *natural = nat_result;
index 73b8da3859dd3226a303164e71ffd973d8d28ca8..eb82eb8878a9e2f4c2d8b2d6024e8db521579c31 100644 (file)
@@ -356,7 +356,6 @@ struct _GtkWidgetPrivate
   guint vexpand_set           : 1; /* instead of computing from children */
 
   /* SizeGroup related flags */
-  guint sizegroup_visited     : 1;
   guint have_size_groups      : 1;
 
   /* The widget's name. If the widget does not have a name
@@ -13817,19 +13816,6 @@ _gtk_widget_set_height_request_needed (GtkWidget *widget,
   widget->priv->height_request_needed = height_request_needed;
 }
 
-gboolean
-_gtk_widget_get_sizegroup_visited (GtkWidget    *widget)
-{
-  return widget->priv->sizegroup_visited;
-}
-
-void
-_gtk_widget_set_sizegroup_visited (GtkWidget    *widget,
-                                  gboolean      visited)
-{
-  widget->priv->sizegroup_visited = visited;
-}
-
 void
 _gtk_widget_add_sizegroup (GtkWidget    *widget,
                           gpointer      group)
index 4ee04e33cdcf3f0919d07d93de58c0e1bdaaacd5..0a0fe898f76e85c2def382b706fc4134a886a277 100644 (file)
@@ -87,9 +87,6 @@ gboolean     _gtk_widget_get_height_request_needed (GtkWidget *widget);
 void         _gtk_widget_set_height_request_needed (GtkWidget *widget,
                                                     gboolean   height_request_needed);
 
-gboolean     _gtk_widget_get_sizegroup_visited (GtkWidget    *widget);
-void         _gtk_widget_set_sizegroup_visited (GtkWidget    *widget,
-                                               gboolean      visited);
 void         _gtk_widget_add_sizegroup         (GtkWidget    *widget,
                                                gpointer      group);
 void         _gtk_widget_remove_sizegroup      (GtkWidget    *widget,